﻿//-----------------------------------------------------------------------
// <copyright>
// This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
// See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
// </copyright>
//----------------------------------------------------------------------- 
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using Fulcrum.DispatcherProxies;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Fulcrum.UnitTests.DispatcherProxies
{
    [TestClass]
    public class CSharpHelpTests
    {
        public CSharpHelpTests()
        {
            // nothing
        }

        [TestMethod]
        public void TestCShartpHelpAddToListFirstNoFormat()
        {
            StringBuilder sb = new StringBuilder();
            CSharpHelp.AddToList(sb, "first");

            Assert.AreEqual("first", sb.ToString());
        }

        [TestMethod]
        public void TestCShartpHelpAddToListFirstFormat()
        {
            StringBuilder sb = new StringBuilder();
            CSharpHelp.AddToList(sb, "first {0}", 1);

            Assert.AreEqual("first 1", sb.ToString());
        }

        [TestMethod]
        public void TestCShartpHelpAddToListSecondNoFormat()
        {
            StringBuilder sb = new StringBuilder();
            CSharpHelp.AddToList(sb, "first");
            CSharpHelp.AddToList(sb, "second");

            Assert.AreEqual("first, second", sb.ToString());
        }

        [TestMethod]
        public void TestCShartpHelpAddToListSecondFormat()
        {
            StringBuilder sb = new StringBuilder();
            CSharpHelp.AddToList(sb, "first {0}", 1);
            CSharpHelp.AddToList(sb, "second {0}", 2);

            Assert.AreEqual("first 1, second 2", sb.ToString());
        }

        [TestMethod]
        public void TestCSharpHelpCreateMethodNameNoParameters()
        {
            var parameters = GetEmptyParameterSet();
            var name = CSharpHelp.CreateMethodName("Method", parameters);

            Assert.AreEqual("Method", name);
        }

        private static List<ParameterInfo> GetEmptyParameterSet()
        {
            var parameters = new List<ParameterInfo>();
            return parameters;
        }

        [TestMethod]
        public void TestCSharpHelpCreateMethodNameOneParameter()
        {
            var parameters = GetSingleParameterSet();
            var name = CSharpHelp.CreateMethodName("Method", parameters);

            Assert.AreEqual("MethodInt32", name);
        }

        private ParameterInfo[] GetSingleParameterSet()
        {
            var type = this.GetType();
            var method = type.GetMethod("OneParameterMethod");
            var parameters = method.GetParameters();
            return parameters;
        }

        public void OneParameterMethod(int value)
        {
            throw new NotImplementedException();
        }

        [TestMethod]
        public void TestCSharpHelpCreateMethodNameManyParameters()
        {
            var parameters = GetManyParameterSet();
            var name = CSharpHelp.CreateMethodName("Method", parameters);

            Assert.AreEqual("MethodInt32StringBoolean", name);
        }

        private ParameterInfo[] GetManyParameterSet()
        {
            var type = this.GetType();
            var method = type.GetMethod("ManyParametersMethod");
            var parameters = method.GetParameters();
            return parameters;
        }

        public void ManyParametersMethod(int value, string anotherValue, bool lastValue)
        {
            throw new NotImplementedException();
        }

        [TestMethod]
        public void TestCSharpHelpCreateMethodNameGenericParameters()
        {
            var parameters = GetGenericParameterSet();
            var name = CSharpHelp.CreateMethodName("Method", parameters);

            Assert.AreEqual("MethodICollection_1StringIDictionary_2", name);
        }

        private ParameterInfo[] GetGenericParameterSet()
        {
            var type = this.GetType();
            var method = type.GetMethod("GenericParametersMethod");
            var parameters = method.GetParameters();
            return parameters;
        }

        public void GenericParametersMethod(ICollection<int> values, string anotherValue, IDictionary<string,List<bool>> lastValue)
        {
            throw new NotImplementedException();
        }

        [TestMethod]
        public void TestCSharpHelpCreateParameterDeclarationNoParameters()
        {
            var parameters = GetEmptyParameterSet();
            var result = CSharpHelp.CreateParameterDeclaration(parameters);

            Assert.AreEqual("", result);

        }

        [TestMethod]
        public void TestCSharpHelpCreateParameterDeclarationOneParameter()
        {
            var parameters = GetSingleParameterSet();
            var result = CSharpHelp.CreateParameterDeclaration(parameters);

            Assert.AreEqual("System.Int32 value", result);

        }

        [TestMethod]
        public void TestCSharpHelpCreateParameterDeclarationManyParameters()
        {
            var parameters = GetManyParameterSet();
            var result = CSharpHelp.CreateParameterDeclaration(parameters);

            Assert.AreEqual("System.Int32 value, System.String anotherValue, System.Boolean lastValue", result);

        }

        [TestMethod]
        public void TestCSharpHelpCreateParameterDeclarationGenericParameters()
        {
            var parameters = GetGenericParameterSet();
            var result = CSharpHelp.CreateParameterDeclaration(parameters);

            Assert.AreEqual("System.Collections.Generic.ICollection<System.Int32> values, System.String anotherValue, System.Collections.Generic.IDictionary<System.String, System.Collections.Generic.List<System.Boolean>> lastValue", result);
        }

        [TestMethod]
        public void TestCSharpHelpCreateParameterDeclarationGenericParametersWithPrefix()
        {
            var parameters = GetGenericParameterSet();
            var result = CSharpHelp.CreateParameterDeclaration(parameters, "MyPrefix");

            Assert.AreEqual("System.Collections.Generic.ICollection<System.Int32> MyPrefixvalues, System.String MyPrefixanotherValue, System.Collections.Generic.IDictionary<System.String, System.Collections.Generic.List<System.Boolean>> MyPrefixlastValue", result);
        }

        [TestMethod]
        public void TestCSharpHelpCreateParameterListNoParameters()
        {
            var parameters = GetEmptyParameterSet();
            var result = CSharpHelp.CreateParameterList(parameters);

            Assert.AreEqual("", result);

        }

        [TestMethod]
        public void TestCSharpHelpCreateParameterListOneParameter()
        {
            var parameters = GetSingleParameterSet();
            var result = CSharpHelp.CreateParameterList(parameters);

            Assert.AreEqual("value", result);

        }

        [TestMethod]
        public void TestCSharpHelpCreateParameterListManyParameters()
        {
            var parameters = GetManyParameterSet();
            var result = CSharpHelp.CreateParameterList(parameters);

            Assert.AreEqual("value, anotherValue, lastValue", result);

        }

        [TestMethod]
        public void TestCSharpHelpCreateParameterListGenericParameters()
        {
            var parameters = GetGenericParameterSet();
            var result = CSharpHelp.CreateParameterList(parameters);

            Assert.AreEqual("values, anotherValue, lastValue", result);
        }

        [TestMethod]
        public void TestCSharpHelpCreateParameterListGenericParametersWithPrefix()
        {
            var parameters = GetGenericParameterSet();
            var result = CSharpHelp.CreateParameterList(parameters, "MyPrefix");

            Assert.AreEqual("MyPrefixvalues, MyPrefixanotherValue, MyPrefixlastValue", result);
        }

        [TestMethod]
        public void TestCSharpHelpGetFullTypeNameVoid()
        {
            var type = typeof(void);
            var result = CSharpHelp.GetFullTypeName(type);

            Assert.AreEqual("void", result);
        }

        [TestMethod]
        public void TestCSharpHelpGetFullTypeNameScalar()
        {
            var type = typeof(long);
            var result = CSharpHelp.GetFullTypeName(type);

            Assert.AreEqual("System.Int64", result);
        }

        [TestMethod]
        public void TestCSharpHelpGetFullTypeNameClass()
        {
            var type = typeof(CSharpHelpTests);
            var result = CSharpHelp.GetFullTypeName(type);

            Assert.AreEqual("Fulcrum.UnitTests.DispatcherProxies.CSharpHelpTests", result);
        }

        [TestMethod]
        public void TestCSharpHelpGetFullTypeNameGeneric()
        {
            var type = typeof(List<bool>);
            var result = CSharpHelp.GetFullTypeName(type);

            Assert.AreEqual("System.Collections.Generic.List<System.Boolean>", result);
        }

        [TestMethod]
        public void TestCSharpHelpGetFullTypeNameNestedGeneric()
        {
            var type = typeof(List<IDictionary<string,bool>>);
            var result = CSharpHelp.GetFullTypeName(type);

            Assert.AreEqual("System.Collections.Generic.List<System.Collections.Generic.IDictionary<System.String, System.Boolean>>", result);
        }
    }
}
